package com.jinzhi.jzapi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jinzhi.api.pojo.vo.TokenVO;
import com.jinzhi.common.base.CoreServiceImpl;
import com.jinzhi.common.domain.ConfigDO;
import com.jinzhi.common.exception.IFastException;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.*;
import com.jinzhi.jzapi.domain.UserDO;
import com.jinzhi.jzapi.service.UserService;
import com.jinzhi.jzapi.utils.*;
import com.jinzhi.jzweb.domain.JazUserIntegralDO;
import com.jinzhi.jzweb.service.JazUserIntegralService;
import com.jinzhi.oss.domain.FileDO;
import com.jinzhi.oss.service.FileService;
import com.jinzhi.sys.dao.UserDao;
import com.jinzhi.sys.service.UserRoleService;
import com.jinzhi.wxmp.domain.MpConfigDO;
import com.jinzhi.wxmp.service.MpConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * <pre>
 * </pre>
 *
 * <small> 2018年3月23日 | Aron</small>
 */
@Service
public class UserServiceWxImpl extends CoreServiceImpl<UserDao, UserDO> implements UserService {


    //授权（必填）
    String grant_type = DataEnum.wx_grant_type.getValue();

    //微信url
    String wx_url = DataEnum.wx_authorization_url.getValue();
    @Autowired
    private MpConfigService mpConfigService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private UserDao userDao;

    private FileService sysFileService;

    @Autowired
    private JazUserIntegralService jazUserIntegralService; //积分明细表



    @Override
    public List<UserDO> list1(Map map) {
        return null;
    }

    public String wxurl(String wxId,String code){
        MpConfigDO mpConfigDO = mpConfigService.selectById(wxId);
        //获取登录手机号和密码
        String params = "appid=" + mpConfigDO.getAppId() + "&secret=" + mpConfigDO.getAppSecret() + "&js_code=" + code + "&grant_type=" + grant_type;
        //发送请求
        String sr = HttpRequest.sendGet(wx_url, params);
        return sr;
    }

    @Override
    public Object login(Map member) {
        String wxId = member.get("wxId").toString();
        String encryptedData =member.get("encryptedData").toString();
        String iv =member.get("iv").toString();
        String code =member.get("code").toString();
        String lnviteUserId = member.get("lnviteUserId").toString();
        //Integer wxId, String encryptedData, String iv, String code
        if(member.size()==0){
            throw new JinZhiException(ExceptionEnum.INVALID_PARAM_ERROR.getStatus(),ExceptionEnum.INVALID_PARAM_ERROR.getMessage());
        }

        //调用微信接口获取信息 解析相应内容（转换成json对象）
        JSONObject json = JSONObject.parseObject(wxurl(wxId,code));
        String errCode = null;
        if (null != json.get("errcode")) {
            errCode = json.get("errcode").toString();
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(errCode)) {
            String errMsg = json.getString("errmsg");
            throw new JinZhiException(ExceptionEnum.WX_ERROR_CODE.getStatus(),ExceptionEnum.WX_ERROR_CODE.getMessage()+ errMsg);
        }
        //获取会话密钥（session_key）
        String session_key = json.getString("session_key");
        //用户的唯一标识（openid）
        String openid = json.getString("openid");
        Map<String, Object> map = new HashMap<>();

        try {
            String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            JSONObject object = JSONObject.parseObject(result);
            // 拿到手机号码
            String mobile = object.getString("phoneNumber");
            if (mobile != null) {
                /////////////// 2、根据手机号码查询判断用户是否存在 ////////////////
                log.info("openId:{}", openid);
                UserDO userDO = new UserDO();
                EntityWrapper<UserDO> ew = new EntityWrapper<>();
                ew.eq("mobile",mobile);
               List<UserDO>  userDOS = userDao.selectList(ew);

                if (userDOS != null&&userDOS.size()>0) {
                    userDO = userDOS.get(0);

                        userDO.setCerOpenId(openid);//证书小程序openId
                    userDao.updateById(userDO);
                } else {

//                    if (!lnviteUserId.equals("0")){//不等于0表示是被邀请的用户
//                        userDO.setLnviteUserId(Long.valueOf(lnviteUserId));
//                        userDO.setCurrentPoints("100");//被邀请人获得100积分
//                        userDO.setAccumulatedPoints("100");
//                        UserDO yqrUser = userDao.selectById(lnviteUserId);
//                        yqrUser.setCurrentPoints(String.valueOf(Double.valueOf(yqrUser.getCurrentPoints() == null?"0":yqrUser.getCurrentPoints()) + 200));
//                        yqrUser.setAccumulatedPoints(String.valueOf(Double.valueOf(yqrUser.getAccumulatedPoints() == null?"0":yqrUser.getAccumulatedPoints()) + 200));
//                        userDao.updateById(yqrUser);
//
//                        JazUserIntegralDO yqrUserIntegralDO = new JazUserIntegralDO();
//                        yqrUserIntegralDO.setIntegralDetail("+"+200); //积分
//                        yqrUserIntegralDO.setSysUserid(yqrUser.getId()); //用户id
//                        yqrUserIntegralDO.setIntegralTime(new Date()); //时间
//                        yqrUserIntegralDO.setIntegralWay("邀请新人"); //用途
//                        yqrUserIntegralDO.setCurrentIntegral(yqrUser.getCurrentPoints()); //当前积分
//                        jazUserIntegralService.insert(yqrUserIntegralDO);
//
//                    }

                    userDO.setCurrentPoints(String.valueOf(Double.valueOf(userDO.getCurrentPoints() == null?"0":userDO.getCurrentPoints()) + 100));
                    userDO.setAccumulatedPoints(String.valueOf(Double.valueOf(userDO.getAccumulatedPoints() == null?"0":userDO.getAccumulatedPoints()) + 100));
                    userDO.setUsername(mobile);//默认存入手机号码
//                    String phone = mobile.substring(0, 3) + "****" + mobile.substring(7, mobile.length());
                    userDO.setNickname(generateDefaultNickname());//昵称默认手机号 176****6237
                    userDO.setHeadPortrait("https://jinzhiweiye.oss-cn-hangzhou.aliyuncs.com/2023/04/421/a/head_pic.png"); //第一次登录默认头像
                    userDO.setWxId(Integer.valueOf(wxId));
                    userDO.setCerOpenId(openid);//证书小程序openId
                    userDO.setMobile(mobile);
                    userDO.setType(0);//默认个人会员
                    String password = "123456";
                    String salt = UUIDUtils.get();
                    String encodePasswd = PasswdUtils.get(password, salt);
                    userDO.setSalt(salt);
                    userDO.setPassword(encodePasswd);
                  //  userDO.setMoney(BigDecimal.valueOf(0.0));//默认0元
                    userDO.setGmtCreate(new Date());
                    userDO.setGmtModified(userDO.getGmtCreate());
                    userDO.setStatus(1);//默认正常
                    userDO.setSex(0L);//默认未知

                    List<Long> list = new ArrayList<>();
                    list.add(56L);
                    userDO.setRoleIds(list);

                    userDao.insert(userDO);
//                    UserDO rzrUser = userDO;
//                    JazUserIntegralDO scdlUserIntegralDO = new JazUserIntegralDO();
//                    scdlUserIntegralDO.setIntegralDetail("+" + 100); //积分
//                    scdlUserIntegralDO.setSysUserid(rzrUser.getId()); //用户id
//                    scdlUserIntegralDO.setIntegralTime(new Date()); //时间
//                    scdlUserIntegralDO.setIntegralWay("首次登录"); //用途
//                    scdlUserIntegralDO.setCurrentIntegral(rzrUser.getCurrentPoints()); //当前积分
//                    jazUserIntegralService.insert(scdlUserIntegralDO);
//                    if (!lnviteUserId.equals("0")) {//不等于0表示是被邀请的用户
//                        JazUserIntegralDO rzrUserIntegralDO = new JazUserIntegralDO();
//                        rzrUserIntegralDO.setIntegralDetail("+" + 100); //积分
//                        rzrUserIntegralDO.setSysUserid(rzrUser.getId()); //用户id
//                        rzrUserIntegralDO.setIntegralTime(new Date()); //时间
//                        rzrUserIntegralDO.setIntegralWay("新人入驻"); //用途
//                        rzrUserIntegralDO.setCurrentIntegral(rzrUser.getCurrentPoints()); //当前积分
//                        jazUserIntegralService.insert(rzrUserIntegralDO);
//                    }
                }

                /////////////// 3、生成自定义登录态(jwt token) ////////////////
                //生成,根据openid
                String token = getToken(mobile);

                ///////////////  4、将生成自定义登录态与session_key、openid进行关联 ////////////////
                Map cache = new HashMap();
                cache.put("session_key", session_key);
                cache.put("mobile", mobile);
                EhCacheUtil.put(token, cache);

                /////////////// 5、返回自定义登录态token + 用户信息////////////////
                map.put("isOpenId",true);//20200701 pjr新增isOpenId
                map.put("openId",openid);
                map.put("token", token);
                map.put("userId", userDO.getId());
                map.put("userName", userDO.getUsername());
                map.put("mobile", userDO.getMobile());
                map.put("headPortrait", userDO.getHeadPortrait());
                //登录成功之后，生成token字符串，使用jwt工具类

            } else {
                throw new JinZhiException(ExceptionEnum.INVALID_PHONE_NULL.getStatus(),ExceptionEnum.INVALID_PHONE_NULL.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new JinZhiException(ExceptionEnum.TRY_CATH_ERROY.getStatus(),ExceptionEnum.TRY_CATH_ERROY.getMessage());
        }

        return map;
    }


    public static String generateDefaultNickname() {
        String prefix = "新用户";
        String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuilder nickname = new StringBuilder();

        // 添加四位随机数
        for (int i = 0; i < 4; i++) {
            nickname.append(random.nextInt(10));
        }

        // 添加三个随机字母
        for (int i = 0; i < 3; i++) {
            nickname.append(letters.charAt(random.nextInt(letters.length())));
        }

        // 添加当天的日期日
        SimpleDateFormat sdf = new SimpleDateFormat("dd");
        String day = sdf.format(new Date());
        nickname.append(day);

        // 将所有字符打乱顺序
        List<Character> chars = new ArrayList<>();
        for (char c : nickname.toString().toCharArray()) {
            chars.add(c);
        }
        Collections.shuffle(chars, random);

        // 生成最终的昵称
        StringBuilder finalNickname = new StringBuilder(prefix);
        for (char c : chars) {
            finalNickname.append(c);
        }

        return finalNickname.toString();
    }




    @Override
    public String getToken(String mobile) {
        EntityWrapper<UserDO> wrapper=new EntityWrapper();
        wrapper.like("mobile",mobile);
        List<UserDO>  userDO = userService.selectList(wrapper);
        if (userDO.size()==0) {
            throw new JinZhiException(ApiEnumError.apiAuthorizationWxLoginFailed.getCode(),ApiEnumError.apiAuthorizationWxLoginFailed.getMsg());
        }
        //将用户信息储存到redis里面
        // redisUtil.set(token,userDO.getId(), RedisTime.redisTimeDay);

        return createToken(userDO.get(0));
    }

    private String createToken(UserDO userDO) {
        TokenVO vo = new TokenVO();
        String token = JWTUtil.jzSign(userDO, JwtConfigTime.JwtVerify, JwtConfigTime.time5.longValue());
        //String refreshToken = JWTUtil.sign(userDO.getId() + "", userDO.getId() + userDO.getMobile(), 2l, true);
        vo.setToken(token);
        vo.setRefleshToken(token);
        vo.setTokenExpire(2l);
        vo.setRefreshTokenExpire(7l);
        return vo.getToken();
    }

    @Override
    public UserDO getUserMobile(Long mobile) {
        return null;
    }

    @Override
    public UserDO getUserInfo(String token) {
        return null;
    }

    @Override
    public Map<String, Object> updatePersonalImg(MultipartFile file, String avatar_data, Long userId) throws Exception {
        return null;
    }

    @Override
    public Long userPhone(String phone) {
        return null;
    }

    @Override
    public UserDO getByUserId(Long userId) {
        return null;
    }
}
